1 /***
2 * Lexer.java
3 *
4 * $Author: mballesteros $
5 * $Date: 2003/11/28 19:18:04 $
6 * $Revision: 1.1 $
7 */
8 package net.sf.jec;
9
10 import java.util.ArrayList;
11 import java.util.List;
12
13 /***
14 * <p>{@link Lexer} is as a lexical analyzer for JEC. It decomposes a character
15 * string into a token chain. A pointer to the current element helps parsers
16 * to scan the token chain for valid constructions.</p>
17 * <p>Use {@link getToken} to get the current element. To move the pointer to
18 * the current element use {@link next} and {@link previous}.</p>
19 * <p>This lexer don't consider blank spaces (NL and LF included) as tokens and
20 * removes them. Numbers can contain dots when they represent floating point
21 * values. A String begining with " may contain ' caracters inside and must
22 * terminate with " (and vice versa). Arithmetic and boolean operators are
23 * tokens. Parenthesis, brackets, commas are tokens too.</p>
24 *
25 * @author mballesteros
26 */
27 class Lexer {
28
29 /***
30 * Internal token list
31 */
32 protected List tokens;
33
34 /***
35 * Internal pointer to the current element
36 */
37 protected int current;
38
39 public Lexer(String exp) {
40 int control = 0;
41 tokens = new ArrayList();
42 int i = -1;
43 int len = exp.length();
44 char c;
45 while (true) {
46 i++;
47 if (i >= len)
48 break;
49 c = exp.charAt(i);
50 switch (c) {
51 case ' ' :
52 case '\t' :
53 case '\n' :
54 break;
55 case '.' :
56 case ',' :
57 case '+' :
58 case '-' :
59 case '*' :
60 case '/' :
61 case '%' :
62 case '[' :
63 case ']' :
64 case '(' :
65 case ')' :
66 tokens.add(exp.substring(i, i + 1));
67 break;
68 case '\'' :
69 tokens.add(exp.substring(i, i + 1));
70 StringBuffer sb = new StringBuffer();
71 while (true) {
72 i++;
73 if (i >= len)
74 break;
75 c = exp.charAt(i);
76 if (c == '\'')
77 break;
78 else
79 sb.append(c);
80 }
81 tokens.add(sb.toString());
82 tokens.add(exp.substring(i, i + 1));
83 break;
84 case '\"' :
85 tokens.add(exp.substring(i, i + 1));
86 sb = new StringBuffer();
87 while (true) {
88 i++;
89 if (i >= len)
90 break;
91 c = exp.charAt(i);
92 if (c == '\"')
93 break;
94 else
95 sb.append(c);
96 }
97 tokens.add(sb.toString());
98 tokens.add(exp.substring(i, i + 1));
99 break;
100 case '=' :
101 i++;
102 c = exp.charAt(i);
103 if (c == '=') {
104 tokens.add("==");
105 } else {
106 tokens.add("=");
107 i--;
108 }
109 break;
110 case '!' :
111 i++;
112 c = exp.charAt(i);
113 if (c == '=') {
114 tokens.add("!=");
115 } else {
116 tokens.add("!");
117 i--;
118 }
119 break;
120 case '<' :
121 i++;
122 c = exp.charAt(i);
123 if (c == '=') {
124 tokens.add("<=");
125 } else {
126 tokens.add("<");
127 i--;
128 }
129 break;
130 case '>' :
131 i++;
132 c = exp.charAt(i);
133 if (c == '=') {
134 tokens.add(">=");
135 } else {
136 tokens.add(">");
137 i--;
138 }
139 break;
140 case '&' :
141 i++;
142 c = exp.charAt(i);
143 if (c == '&') {
144 tokens.add("&&");
145 } else {
146 tokens.add("&");
147 i--;
148 }
149 break;
150 case '|' :
151 i++;
152 c = exp.charAt(i);
153 if (c == '|') {
154 tokens.add("||");
155 } else {
156 tokens.add("|");
157 i--;
158 }
159 break;
160 default :
161 StringBuffer tokenSb = new StringBuffer();
162 tokenSb.append(c);
163 boolean isDigit = false;
164 if (Character.isDigit(c))
165 isDigit = true;
166 while (true) {
167 i++;
168 if (i >= len)
169 break;
170 c = exp.charAt(i);
171 if (".,+-*/[]()\"'=!<>%|& ".indexOf(c) < 0) {
172 tokenSb.append(c);
173 } else if (isDigit && c=='.') {
174 tokenSb.append(c);
175 } else {
176 break;
177 }
178 }
179 tokens.add(tokenSb.toString());
180 i--;
181 break;
182 }
183 }
184
185 if (tokens.size() > 0)
186 current = 0;
187 else
188 current = -1;
189
190 /*
191 System.out.println("------ TOKENS -------");
192 for (int j = 0; j < tokens.size(); j++)
193 System.out.println(tokens.get(j));
194 System.out.println("------ /TOKENS -------");
195 */
196 }
197
198 /***
199 * Returns current token
200 *
201 * @return String The current token
202 */
203 public String getToken() {
204 return current >= 0 ? (String) tokens.get(current) : null;
205 }
206
207 /***
208 * Tries to move the pointer to the next token. If <code>true</code> is
209 * returned, {@link getToken} will point to the next token.
210 *
211 * @return boolean False if there are no more tokens.
212 */
213 public boolean next() {
214 if (current < (tokens.size() - 1)) {
215 current++;
216 return true;
217 } else {
218 return false;
219 }
220 }
221
222 /***
223 * Tries to move the pointer to the previous token. If <code>true</code> is
224 * returned, {@link getToken} will point to the previous token.
225 *
226 * @return boolean False if there are no previous tokens.
227 */
228 public boolean previous() {
229 if (current >= 0) {
230 current--;
231 return true;
232 } else {
233 return false;
234 }
235 }
236 }
This page was automatically generated by Maven